import os
import re
import subprocess

class AudioSplitter:
    """
    使用 ffmpeg 按时间点分割音频文件的工具类
    """

    def __init__(self, input_path=None, output_dir=r"C:\Users\33720\Desktop\temp", fmt="wav", ffmpeg_path="ffmpeg"):
        """
        初始化（可提供默认值）
        """
        self.input_path = input_path
        self.output_dir = output_dir
        self.fmt = fmt
        self.ffmpeg_cmd = ffmpeg_path

        # 自动创建输出文件夹
        os.makedirs(self.output_dir, exist_ok=True)

    # ------------------------------------------------------------
    # Setter 函数
    # ------------------------------------------------------------
    def set_input_path(self, path):
        """设置输入文件路径"""
        if not os.path.isfile(path):
            raise FileNotFoundError(f"输入文件不存在: {path}")
        self.input_path = path
        print(f"🎵 已设置输入文件: {self.input_path}")

    def set_output_dir(self, path):
        """设置输出目录"""
        os.makedirs(path, exist_ok=True)
        self.output_dir = path
        print(f"📁 已设置输出目录: {self.output_dir}")

    def set_fmt(self, format_str):
        """设置输出文件格式"""
        allowed = {"wav", "mp3", "aac", "flac", "ogg"}
        if format_str.lower() not in allowed:
            raise ValueError(f"不支持的音频格式: {format_str}（可选: {allowed}）")
        self.fmt = format_str.lower()
        print(f"🎧 已设置输出格式: {self.fmt}")

    def set_ffmpeg_path(self, path):
        """设置 ffmpeg 程序路径"""
        self.ffmpeg_cmd = path
        print(f"⚙️ 已设置 ffmpeg 路径: {self.ffmpeg_cmd}")

    # ------------------------------------------------------------
    # 内部方法
    # ------------------------------------------------------------
    def _time_to_ffmpeg_format(self, time_str):
        """将时间字符串转换为 ffmpeg 可识别的 HH:MM:SS 格式"""
        parts = time_str.split(":")
        if len(parts) == 2:
            return f"00:{parts[0].zfill(2)}:{parts[1].zfill(2)}"
        elif len(parts) == 3:
            return f"{parts[0].zfill(2)}:{parts[1].zfill(2)}:{parts[2].zfill(2)}"
        elif len(parts) == 1:
            return f"00:00:{parts[0].zfill(2)}"
        else:
            raise ValueError(f"时间格式错误: {time_str}")

    def _get_audio_duration(self):
        """使用 ffmpeg 获取音频总时长（HH:MM:SS）"""
        result = subprocess.run(
            [self.ffmpeg_cmd, "-i", self.input_path],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True
        )
        output = result.stdout
        match = re.search(r"Duration: (\d+):(\d+):(\d+\.\d+)", output)
        if not match:
            raise ValueError("无法获取音频总时长，请确认文件是否有效")

        return f"{match.group(1)}:{match.group(2)}:{int(float(match.group(3)))}"

    # ------------------------------------------------------------
    # 核心：分割音频
    # ------------------------------------------------------------
    def split_audio(self, time_points):
        """
        根据时间点切割音频文件
        :param time_points: 时间点列表，如 ["03:30", "07:15"]
        """
        if not self.input_path:
            raise ValueError("未设置输入文件路径，请先调用 set_input_path()")

        sorted_points = sorted(time_points)
        points = ["00:00:00"] + [self._time_to_ffmpeg_format(t) for t in sorted_points]
        duration = self._get_audio_duration()
        points.append(duration)
        result=[]
        for i in range(len(points) - 1):
            start = points[i]
            end = points[i + 1]
            start_str = start.replace(":", "_")
            end_str = end.replace(":", "_")
            output_file = os.path.join(self.output_dir, f"{start_str}-{end_str}.{self.fmt}")

            cmd = [
                self.ffmpeg_cmd,
                "-y",
                "-i", self.input_path,
                "-ss", start,
                "-to", end,
                "-c", "copy",
                output_file
            ]
            subprocess.run(cmd, check=True)
            result.append(f"✅ 导出片段: {output_file} ({start} ~ {end})")
        return "\n".join(result)
        print("\n🎧 音频切割完成！")

# ------------------------------------------------------------
# 使用示例
# ------------------------------------------------------------
if __name__ == "__main__":
    # 初始化时可以不传任何参数
    splitter = AudioSplitter()

    # 通过 setter 重新设置属性
    splitter.set_input_path(r"C:\Users\33720\Desktop\123.wav")
    splitter.set_output_dir(r"C:\Users\33720\Desktop\s2")
    splitter.set_fmt("wav")

    # 分割点（单位：MM:SS）
    time_points = ["2:20"]
    splitter.split_audio(time_points)
